#pragma once
#include <unordered_map>

#include "mocker.h"

struct HookObjectMgr {
  static HookObjectMgr& GetInstance() {
    static HookObjectMgr objMgr{};
    return objMgr;
  }

  void* Invoke(void* api) {
    return m_invokeObjs[api]->GetMethod();
  }

  AddrModifier& MakeHookObj(void* api, void* stub) {
    m_invokeObjs[api] = new(std::nothrow) AddrModifier(api, stub);
    return *(m_invokeObjs[api]);
  }

  void RemoveHookObj(void* api) {
    if (auto iter = m_invokeObjs.find(api); iter != m_invokeObjs.end()) {
      AddrModifier* obj = m_invokeObjs[api];
      m_invokeObjs.erase(api);
      delete obj;
    }
  }

private:
  HookObjectMgr() = default;

  ~HookObjectMgr() {
    for (auto [api, obj] : m_invokeObjs) {
      delete obj;
    }
  }

  std::unordered_map<void*, AddrModifier*> m_invokeObjs;
};